package com.face.recognition.service.impl;

import com.alibaba.fastjson.JSON;
import com.face.recognition.common.WebSocketServer;
import com.face.recognition.config.HCNetSDK;
import com.face.recognition.domain.FaceRecognitionResponse;
import com.face.recognition.service.FaceRecognitionService;
import com.face.recognition.service.HKNetSdkService;
import com.face.recognition.utils.Base64Utils;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 * @program: facedemo
 * @description:
 * @author: 作者名字
 * @create: 2021-03-20 14:18
 **/
@Service
public class HKNetSdkServiceImpl implements HKNetSdkService {

    @Autowired
    private FaceRecognitionService faceRecognitionService;
    @Autowired
    private WebSocketServer webSocketServer;

    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    static int lUserID = -1;//用户句柄
    static int dwState = -1; //人员信息状态
    static int dwFaceState = -1; //下发人脸数据状态
    static int iCharEncodeType = 0;//设备字符集
    static int lAlarmHandle = -1;//报警布防句柄
    int lListenHandle;//报警监听句柄

    public static HCNetSDK.FMSGCallBack fMSFCallBack;//报警回调函数实现
    public static HCNetSDK.FMSGCallBack_V31 fMSFCallBack_V31;//报警回调函数实现

    public String Login() {
        hCNetSDK.NET_DVR_Init();
        //注册
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();//设备登录信息

        String m_sDeviceIP = "169.254.13.1";//设备ip地址
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());

        String m_sUsername = "admin";//设备用户名
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());

        String m_sPassword = "zdxk123456";//设备密码
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());

        m_strLoginInfo.wPort = 8000;
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();

        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();//设备信息
        lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (lUserID == -1) {
            String temp = "登录失败，错误码为" + hCNetSDK.NET_DVR_GetLastError();
            System.out.println(temp);
            return temp;
        } else {
            String temp = "登录成功！";
            System.out.println(temp);
            iCharEncodeType = m_strDeviceInfo.byCharEncodeType;
            return temp;
        }
    }

    public String GetAbility() {

        return null;
    }

    public void AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser){
        switch (lCommand){
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT: //实时人脸抓拍上传
                System.out.println("低于设定拍照阈值，请重新识别");
                HCNetSDK.NET_VCA_FACESNAP_RESULT strFaceSnapInfo = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
                strFaceSnapInfo.write();
                Pointer pFaceSnapInfo = strFaceSnapInfo.getPointer();
                pFaceSnapInfo.write(0, pAlarmInfo.getByteArray(0, strFaceSnapInfo.size()), 0, strFaceSnapInfo.size());
                strFaceSnapInfo.read();
                if(strFaceSnapInfo.dwFaceScore>60) {
                    SimpleDateFormat df = new SimpleDateFormat ("yyyyMMddHHmmss");//设置日期格式
                    String time = df.format (new Date());// new Date()为获取当前系统时间
                    System.out.println("face score is " + strFaceSnapInfo.dwFaceScore+" point");
                    try {
                        //设置图片保存路径
//                        FileOutputStream big = new FileOutputStream ("D:\\FaceImg\\SignIn\\" + time + "big.jpg");
                        FileOutputStream small = new FileOutputStream("D:\\FaceImg\\SignIn\\" + time + "small.jpg");
                        try {
                            small.write(strFaceSnapInfo.pBuffer1.getByteArray(0, strFaceSnapInfo.dwFacePicLen), 0, strFaceSnapInfo.dwFacePicLen);
                            small.close();
//                            big.write (strFaceSnapInfo.pBuffer2.getByteArray (0, strFaceSnapInfo.dwBackgroundPicLen), 0, strFaceSnapInfo.dwBackgroundPicLen);
//                            big.close ();

                            File file = new File("D:\\FaceImg\\SignIn\\" + time + "small.jpg");
                            String base = Base64Utils.ImageToBase64(file);
                            FaceRecognitionResponse signInResponse = faceRecognitionService.signIn(file);
                            HashMap<String, Object> map = new HashMap<>();
                            if(signInResponse.getCode() == 200) {
                                map.put("img", base);
                                map.put("msg", signInResponse.getMsg());
                                webSocketServer.onMessage(JSON.toJSONString(map));
                            } else {
                                map.put("img", base);
                                map.put("msg", signInResponse.getMsg());
                                webSocketServer.onMessage(JSON.toJSONString(map));
                            }
//                            FileSystemResource resource = new FileSystemResource("D:\\Picture\\" + time + "big.jpg");
//                            String url = "http://114.115.232.206:8089/face/signin";
//                            MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
//                            param.add("file", resource);
//                            param.add("id", time);
//                            RestTemplate restTemplate = new RestTemplate();
//                            FaceResponse faceResponse = restTemplate.postForObject(url, param, FaceResponse.class);
//                            if(faceResponse.getCode() == 200) {
//                                System.out.println(faceResponse.getMsg());
//                            }
                        } catch (IOException ex) {
                            ex.printStackTrace ( );
                        }

                    } catch (FileNotFoundException ex) {
                        ex.printStackTrace ( );
                    }
                }
                break;
        }

    }

    public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31
    {
        //报警信息回调函数

        public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser)
        {
            AlarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
            return true;
        }
    }

    public String SetupAlarmChan() {
        if (lUserID == -1)
        {
            JOptionPane.showMessageDialog(null, "请先注册");
            return "请先注册";
        }
        if (lAlarmHandle < 0)//尚未布防,需要布防
        {
            if (fMSFCallBack_V31 == null)
            {
                fMSFCallBack_V31 = new FMSGCallBack_V31();
                Pointer pUser = null;
                if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(fMSFCallBack_V31, pUser))
                {
                    System.out.println("设置回调函数失败!");
                }
            }
            HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
            HCNetSDK.NET_VCA_FACESNAPCFG m_faceInfo = new HCNetSDK.NET_VCA_FACESNAPCFG();
            IntByReference pInt = new IntByReference(0);
            m_faceInfo.write();
            boolean st = hCNetSDK.NET_DVR_GetDVRConfig(lUserID, hCNetSDK.NET_DVR_GET_FACESNAPCFG, 1, m_faceInfo.getPointer(), m_faceInfo.size(), pInt);
            m_faceInfo.read();
            System.out.println(hCNetSDK.NET_DVR_GetLastError());
            m_strAlarmInfo.dwSize=m_strAlarmInfo.size();
            m_strAlarmInfo.byLevel=1;//智能交通布防优先级：0- 一等级（高），1- 二等级（中），2- 三等级（低）
            m_strAlarmInfo.byAlarmInfoType=1;//智能交通报警信息上传类型：0- 老报警信息（NET_DVR_PLATE_RESULT），1- 新报警信息(NET_ITS_PLATE_RESULT)
            m_strAlarmInfo.byDeployType =1; //布防类型(仅针对门禁主机、人证设备)：0-客户端布防(会断网续传)，1-实时布防(只上传实时数据)
            m_strAlarmInfo.write();
            lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
            if (lAlarmHandle == -1)
            {
                //JOptionPane.showMessageDialog(null, "布防失败，错误号:" +  hCNetSDK.NET_DVR_GetLastError());
                return "布防失败，错误号:" +  hCNetSDK.NET_DVR_GetLastError();
            }
            else
            {
                //JOptionPane.showMessageDialog(null, "布防成功");
                return "布防成功";
            }
        }
        return "";
    }

}

